import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Drawer extends JPanel implements MouseMotionListener, MouseListener, KeyListener, ActionListener
{
	private Graphics2D g2D;
	private Graphics2D gimage;
	private BufferedImage bimage;
	private Environment e;
	private Font titleText;
	private Font smallText;
	private Font upgradeText;
	private UpgradeScreen upgradeScreen;
	
	public Drawer(){}
	
	public Drawer(Environment e) 
	{
		this.e=e;
        titleText = new Font("Monospaced", 1, 30);
        smallText = new Font("Monospaced",1,20);
        upgradeText = new Font("Monospaced",1,10);
        bimage = new BufferedImage(e.getWidth(), e.getHeight(), BufferedImage.TYPE_INT_RGB);
        gimage = bimage.createGraphics();

        addMouseMotionListener(this);
        addMouseListener(this);
        addKeyListener(this);
	}
	
	public void paint(Graphics g)
	{
		super.paint(g);
		g.drawLine(0,0,getWidth(),getHeight());
        bimage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
        gimage = bimage.createGraphics();
        upgradeScreen = new UpgradeScreen(this,getWidth(),getHeight(),e);
		g2D = (Graphics2D) g;
        bimage = new BufferedImage(e.getWidth(), e.getHeight(), BufferedImage.TYPE_INT_RGB);
        gimage = bimage.createGraphics();
		if(e.isUpgrading()){
			
			gimage=upgradeScreen.paint(gimage);
			setGimage(gimage);
		}else{
		gimage.setColor(new Color(0,12,58));
		gimage.fillRect(0, 0, getWidth(),  getHeight());
		gimage.setColor(new Color(255,255,255));
		gimage.draw(new Rectangle(48,48,503,503));
		gimage.setFont(smallText);
		gimage.setColor(new Color(20,170,20));
		gimage = drawCenteredString(gimage,String.valueOf("Points: " + e.getSnake().getPoints()), 300, 575);
		setGimage(e.getSnake().Update(getGimage()));
		}
		g2D.drawImage(bimage,null,0,0);
	}

		
	private Shape Triangle(int x1,int y1,int x2,int y2,int x3, int y3) {
		int[] xCoords = new int[3];
		xCoords[0]=x1;
		xCoords[1]=x2;
		xCoords[2]=x3;
		int[] yCoords = new int[3];
		yCoords[0]=y1;
		yCoords[1]=y2;
		yCoords[2]=y3;
		
		return new Polygon(xCoords,yCoords,3);
	}

	public Graphics2D drawCenteredString(Graphics2D gimage, String str,int x, int y){
		FontMetrics fm = gimage.getFontMetrics();
		Rectangle2D rect = fm.getStringBounds(str, gimage);
		gimage.drawString(str, (int) (x-rect.getWidth()/2), (int) (y+rect.getHeight()/4));
		return gimage;
	}
	
	/**
	 * @return the titleText
	 */
	public Font getTitleText() {
		return titleText;
	}

	/**
	 * @param titleText the titleText to set
	 */
	public void setTitleText(Font titleText) {
		this.titleText = titleText;
	}

	/**
	 * @return the smallText
	 */
	public Font getSmallText() {
		return smallText;
	}

	/**
	 * @param smallText the smallText to set
	 */
	public void setSmallText(Font smallText) {
		this.smallText = smallText;
	}

	

	/**
	 * @return the gimage
	 */
	public Graphics2D getGimage() {
		return gimage;
	}

	/**
	 * @param gimage the gimage to set
	 */
	public void setGimage(Graphics2D gimage) {
		this.gimage = gimage;
	}

	/**
	 * @return the upgradeText
	 */
	public Font getUpgradeText() {
		return upgradeText;
	}

	/**
	 * @param upgradeText the upgradeText to set
	 */
	public void setUpgradeText(Font upgradeText) {
		this.upgradeText = upgradeText;
	}

	/**
	 * @return the upgradeScreen
	 */
	public UpgradeScreen getUpgradeScreen() {
		return upgradeScreen;
	}

	/**
	 * @param upgradeScreen the upgradeScreen to set
	 */
	public void setUpgradeScreen(UpgradeScreen upgradeScreen) {
		this.upgradeScreen = upgradeScreen;
	}
	
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		char letter = e.getKeyChar();
		if(!this.e.isUpgrading())
			this.e.getSnake().keyPressed(letter);
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		char letter = e.getKeyChar();
		this.e.getSnake().keyReleased(letter);
		
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		char letter = e.getKeyChar();
		if(letter == ' '){
			if(this.e.isUpgrading()==true){
				this.e.setUpgrading(false);
			}
		}
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		mousePressedEvent(e);
		// TODO Auto-generated method stub
		if(getUpgradeScreen().getFoodDecrement().contains(e.getX(), e.getY())){
			this.e.getSnake().downgradeFood();
		}
		else if(getUpgradeScreen().getFoodIncrement().contains(e.getX(), e.getY())){
			this.e.getSnake().upgradeFood();
		}
		else if(getUpgradeScreen().getGridDecrement().contains(e.getX(), e.getY())){
			this.e.getSnake().upgradeGrid();
		}
		else if(getUpgradeScreen().getGridIncrement().contains(e.getX(), e.getY())){
			this.e.getSnake().downgradeGrid();
		}
	}

	private void mousePressedEvent(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}



	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
	}
}
